package com.wmx.eureka_client2020.controller;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.List;

/**
 * EurekaClient 获取注册的服务实例
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2022/12/7 9:22
 */
@SuppressWarnings("all")
@RestController
public class SystemController {

    @Resource
    private EurekaClient eurekaClient;

    /**
     * 根据指定的微服务名称，获取它的实例信息.
     * http://localhost:9223/eureka-instance?applicationName=frs-server2
     * <p>
     * InstanceInfo EurekaClient.getNextServerFromEureka(String virtualHostname, boolean secure)
     * 1、获取下一个可能的服务实例，以处理从eureka接收的注册表信息中的请求。
     * 2、注意：如果服务是多实例，下一个服务是以循环方式选择的，默认情况下，此方法只返回当前使用的服务器。
     * 3、virtualHostname：虚拟主机名称，Eureka 服务端主页中 application 选项下的服务名称
     * * 如果没有找到指定的 virtualHostname，则抛出异常：java.lang.RuntimeException: No matches for the virtual host name
     * 4、secure：表示是否为 https 方式
     * <br/>
     *
     * @param applicationName ：在 Eureka 服务器上注册的微服务名称
     * @return
     */
    @GetMapping("eureka-instance")
    public String getEurekaInstance(String applicationName) {
        if (applicationName == null || "".equals(applicationName)) {
            return "<p style='color:red'>请携带 applicationName 参数...</p>";
        }
        InstanceInfo instanceInfo;
        try {
            instanceInfo = eurekaClient.getNextServerFromEureka(applicationName, false);
        } catch (Exception e) {
            return "<p style='color:red'>" + applicationName + " 微服务名不存在...</p>";
        }
        String actionTypeName = instanceInfo.getActionType().name();
        String appGroupName = instanceInfo.getAppGroupName();
        String hostName = instanceInfo.getHostName();
        String id = instanceInfo.getId();
        String instanceId = instanceInfo.getInstanceId();
        String ipAddr = instanceInfo.getIPAddr();
        String healthCheckUrl = instanceInfo.getHealthCheckUrl();
        //返回如：http://172.27.35.7:8000/
        String homePageUrl = instanceInfo.getHomePageUrl();

        //将所有数据封装成 json 格式返回，这样网页上看起来会更加清晰
        JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
        ObjectNode objectNode = nodeFactory.objectNode();
        objectNode.put("actionTypeName", actionTypeName);
        objectNode.put("appGroupName", appGroupName);
        objectNode.put("hostName", hostName);
        objectNode.put("id", id);
        objectNode.put("instanceId", instanceId);
        objectNode.put("ipAddr", ipAddr);
        objectNode.put("healthCheckUrl", healthCheckUrl);
        objectNode.put("homePageUrl", homePageUrl);

        // {
        //     "actionTypeName": "ADDED",
        //         "appGroupName": null,
        //         "hostName": "10.104.65.195",
        //         "id": "LocalInfogoHost:frs-server2:9222",
        //         "instanceId": "LocalInfogoHost:frs-server2:9222",
        //         "ipAddr": "10.104.65.195",
        //         "healthCheckUrl": "http://10.104.65.195:9222/actuator/health",
        //         "homePageUrl": "http://10.104.65.195:9222/"
        // }
        return objectNode.toString();
    }

    /**
     * 获取注册中心中全部服务与实例信息
     * http://localhost:9222/eureka-applications?applicationName=frs-server2
     * <p>
     * Applications EurekaClient.getApplications()：获取注册中心全部的应用/服务信息。
     * Application Applications.getRegisteredApplications(String appName)
     * 1、获取给定应用程序名称的所有已注册应用程序的列表。
     * List<Application> Applications.getRegisteredApplications()
     * 1、从eureka获取所有注册的<em>应用程序</em>的列表。
     * List<InstanceInfo> Application.getInstances()
     * 1、获取与此特定应用程序关联的实例列表。
     *
     * @param applicationName ：服务名，不为空时，查询指定服务的全部实例信息；为空时查询所有服务的实例信息。
     * @return
     */
    @GetMapping("eureka-applications")
    public String getEurekaApplications(String applicationName) {
        Applications applications = eurekaClient.getApplications();
        JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
        if (StringUtils.isNotBlank(applicationName)) {
            Application application = applications.getRegisteredApplications(applicationName);
            String name = application.getName();
            List<InstanceInfo> instanceInfos = application.getInstances();

            ArrayNode arrayNode = nodeFactory.arrayNode();
            ObjectNode rootObjectNode = nodeFactory.objectNode();
            rootObjectNode.put("name", name);
            rootObjectNode.put("instanceInfos", arrayNode);
            for (InstanceInfo instanceInfo : instanceInfos) {
                ObjectNode objectNode = nodeFactory.objectNode();
                objectNode.put("actionTypeName", instanceInfo.getActionType().name());
                objectNode.put("appGroupName", instanceInfo.getAppGroupName());
                objectNode.put("hostName", instanceInfo.getHostName());
                objectNode.put("id", instanceInfo.getId());
                objectNode.put("instanceId", instanceInfo.getInstanceId());
                objectNode.put("ipAddr", instanceInfo.getIPAddr());
                objectNode.put("healthCheckUrl", instanceInfo.getHealthCheckUrl());
                objectNode.put("homePageUrl", instanceInfo.getHomePageUrl());
                arrayNode.add(objectNode);
            }
            // {"name":"FRS-SERVER2","instanceInfos":[{"actionTypeName":"ADDED","appGroupName":null,"hostName":"10.104.65.195","id":"LocalInfogoHost:frs-server2:9222","instanceId":"LocalInfogoHost:frs-server2:9222","ipAddr":"10.104.65.195","healthCheckUrl":"http://10.104.65.195:9222/actuator/health","homePageUrl":"http://10.104.65.195:9222/"},{"actionTypeName":"ADDED","appGroupName":null,"hostName":"10.104.65.195","id":"LocalInfogoHost:frs-server2:9223","instanceId":"LocalInfogoHost:frs-server2:9223","ipAddr":"10.104.65.195","healthCheckUrl":"http://10.104.65.195:9223/actuator/health","homePageUrl":"http://10.104.65.195:9223/"}]}
            return rootObjectNode.toString();
        }

        List<Application> registeredApplications = applications.getRegisteredApplications();
        ArrayNode rootArrayNode = nodeFactory.arrayNode();
        for (Application application : registeredApplications) {
            String name = application.getName();
            List<InstanceInfo> instanceInfos = application.getInstances();

            ArrayNode arrayNode = nodeFactory.arrayNode();
            ObjectNode rootObjectNode = nodeFactory.objectNode();
            rootObjectNode.put("name", name);
            rootObjectNode.put("instanceInfos", arrayNode);
            rootArrayNode.add(rootObjectNode);
            for (InstanceInfo instanceInfo : instanceInfos) {
                ObjectNode objectNode = nodeFactory.objectNode();
                objectNode.put("actionTypeName", instanceInfo.getActionType().name());
                objectNode.put("appGroupName", instanceInfo.getAppGroupName());
                objectNode.put("hostName", instanceInfo.getHostName());
                objectNode.put("id", instanceInfo.getId());
                objectNode.put("name", name);
                objectNode.put("instanceId", instanceInfo.getInstanceId());
                objectNode.put("ipAddr", instanceInfo.getIPAddr());
                objectNode.put("healthCheckUrl", instanceInfo.getHealthCheckUrl());
                objectNode.put("homePageUrl", instanceInfo.getHomePageUrl());
                arrayNode.add(objectNode);
            }
        }
        // [{"name":"GATEWAY-SERVER2","instanceInfos":[{"actionTypeName":"ADDED","appGroupName":null,"hostName":"10.104.65.195","id":"LocalInfogoHost:gateway-server2:8000","name":"GATEWAY-SERVER2","instanceId":"LocalInfogoHost:gateway-server2:8000","ipAddr":"10.104.65.195","healthCheckUrl":"http://10.104.65.195:8000/actuator/health","homePageUrl":"http://10.104.65.195:8000/"}]},{"name":"FRAMEWORK-SERVER2","instanceInfos":[{"actionTypeName":"ADDED","appGroupName":null,"hostName":"10.104.65.195","id":"10.104.65.195:23301","name":"FRAMEWORK-SERVER2","instanceId":"10.104.65.195:23301","ipAddr":"10.104.65.195","healthCheckUrl":"http://10.104.65.195:23301/actuator/health","homePageUrl":"http://10.104.65.195:23301/"}]},{"name":"FRAMEWORK-ENGIN2","instanceInfos":[{"actionTypeName":"ADDED","appGroupName":null,"hostName":"10.104.65.195","id":"LocalInfogoHost:framework-engin2:7022","name":"FRAMEWORK-ENGIN2","instanceId":"LocalInfogoHost:framework-engin2:7022","ipAddr":"10.104.65.195","healthCheckUrl":"http://10.104.65.195:7022/actuator/health","homePageUrl":"http://10.104.65.195:7022/"}]},{"name":"FRAMEWORK-WEB2","instanceInfos":[{"actionTypeName":"ADDED","appGroupName":null,"hostName":"LocalInfogoHost","id":"LocalInfogoHost:framework-web2:22306","name":"FRAMEWORK-WEB2","instanceId":"LocalInfogoHost:framework-web2:22306","ipAddr":"10.104.65.195","healthCheckUrl":"http://LocalInfogoHost:22306/actuator/health","homePageUrl":"http://LocalInfogoHost:22306/"}]},{"name":"ELEMENT-SERVER2","instanceInfos":[{"actionTypeName":"ADDED","appGroupName":null,"hostName":"10.104.65.195","id":"LocalInfogoHost:element-server2:8105","name":"ELEMENT-SERVER2","instanceId":"LocalInfogoHost:element-server2:8105","ipAddr":"10.104.65.195","healthCheckUrl":"http://10.104.65.195:8105/actuator/health","homePageUrl":"http://10.104.65.195:8105/"}]},{"name":"WORKFLOW-ENGIN2","instanceInfos":[{"actionTypeName":"ADDED","appGroupName":null,"hostName":"10.104.65.195","id":"10.104.65.195:8103","name":"WORKFLOW-ENGIN2","instanceId":"10.104.65.195:8103","ipAddr":"10.104.65.195","healthCheckUrl":"http://10.104.65.195:8103/actuator/health","homePageUrl":"http://10.104.65.195:8103/"}]},{"name":"FRS-SERVER2","instanceInfos":[{"actionTypeName":"ADDED","appGroupName":null,"hostName":"10.104.65.195","id":"LocalInfogoHost:frs-server2:9223","name":"FRS-SERVER2","instanceId":"LocalInfogoHost:frs-server2:9223","ipAddr":"10.104.65.195","healthCheckUrl":"http://10.104.65.195:9223/actuator/health","homePageUrl":"http://10.104.65.195:9223/"},{"actionTypeName":"ADDED","appGroupName":null,"hostName":"10.104.65.195","id":"LocalInfogoHost:frs-server2:9222","name":"FRS-SERVER2","instanceId":"LocalInfogoHost:frs-server2:9222","ipAddr":"10.104.65.195","healthCheckUrl":"http://10.104.65.195:9222/actuator/health","homePageUrl":"http://10.104.65.195:9222/"}]},{"name":"OAUTH2-SERVER2","instanceInfos":[{"actionTypeName":"ADDED","appGroupName":null,"hostName":"10.104.65.195","id":"LocalInfogoHost:oauth2-server2:8002","name":"OAUTH2-SERVER2","instanceId":"LocalInfogoHost:oauth2-server2:8002","ipAddr":"10.104.65.195","healthCheckUrl":"http://10.104.65.195:8002/actuator/health","homePageUrl":"http://10.104.65.195:8002/"}]},{"name":"WORKFLOW-SERVER2","instanceInfos":[{"actionTypeName":"ADDED","appGroupName":null,"hostName":"10.104.65.195","id":"10.104.65.195:8104","name":"WORKFLOW-SERVER2","instanceId":"10.104.65.195:8104","ipAddr":"10.104.65.195","healthCheckUrl":"http://10.104.65.195:8104/actuator/health","homePageUrl":"http://10.104.65.195:8104/"}]},{"name":"BGT-BASIC-SERVER","instanceInfos":[{"actionTypeName":"ADDED","appGroupName":null,"hostName":"10.104.65.195","id":"10.104.65.195:9000","name":"BGT-BASIC-SERVER","instanceId":"10.104.65.195:9000","ipAddr":"10.104.65.195","healthCheckUrl":"http://10.104.65.195:9000/actuator/health","homePageUrl":"http://10.104.65.195:9000/"}]}]
        return rootArrayNode.toString();
    }

    public static void main(String[] args) {
        RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
        /**
         * String getName()：返回表示正在运行的Java虚拟机的名称
         * 1、通常格式为：进程PID@计算机名称
         */
        // 59372@wangMaoXiong
        System.out.println(runtimeMXBean.getName());
    }


}